import { Sequelize,DataTypes } from "sequelize"

//链接数据库
const sequelize = new Sequelize({
    dialect: 'sqlite',
    storage: './data/database.sqlite'
})

//定义和规范化模型
function defineModel(name,attributes){
    let attrs = {}
    for (let key in attributes){
        let value = attributes[key]
        if(typeof value == 'object' || value['type']){
            value.allowNull = value.allowNull || false
            attrs[key] = value
        } else {
            attrs[key] = {
                type: value,
                allowNull: false
            }
        }
    }

    attrs.id = {
        type: DataTypes.UUID,
        primaryKey:true,
        defaultValue: DataTypes.UUIDV4
    }
    attrs.createdAt = {
        type: DataTypes.BIGINT,
        allowNull: false
    }
    attrs.updatedAt = {
        type: DataTypes.BIGINT,
        allowNull: false
    }
    attrs.version = {
        type: DataTypes.BIGINT,
        allowNull: false
    }

    return sequelize.define(name,attrs,{
        tableName:name,
        timestamps:false,
        hooks:{
            beforeValidate:function(obj){
                let now = Date.now()
                if(obj.isNewRecord){
                    console.log('will create entity...' + obj)
                    obj.createdAt = now
                    obj.updatedAt = now
                    obj.version = 0
                }else{
                    console.log('will update entity...')
                    obj.updatedAt = now
                    obj.version++
                }
            }
        }
    })
}


const TYPES = ['STRING', 'INTEGER', 'BIGINT', 'TEXT', 'DOUBLE', 'DATEONLY', 'BOOLEAN','UUID']


//构建导出对象
let exp = {
    defineModel: defineModel,
    sync: async () => {
        // only allow create ddl in non-production environment:
        if (process.env.NODE_ENV !== 'production') {
            await sequelize.sync();
        } else {
            throw new Error('Cannot sync() when NODE_ENV is set to \'production\'.');
        }
    }
}
for (let type of TYPES) {
    exp[type] = DataTypes[type]
}

export default exp